package com.iwhalecloud.bss.kite.cucc.listener.handler;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsPriceFactorService;
import com.iwhalecloud.bss.kite.cucc.client.dto.goods.factor.PriceFactorDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.PriceFactorsCache;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.util.CalculateDiscountsUtil;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdFeeCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.iwhalecloud.bss.kite.service.context.ServiceContext;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;

/**
 * @Description 计价因子处理类
 * @Author deng.gang
 * @Date 2021/11/13 4:56 下午
 */
@Component
public class CuccPriceFactorHandler {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private IGoodsPriceFactorService goodsPriceFactorService;

    public void refreshStandardPrice(KiteAttr attr, KiteInst inst, AttrData data) {
        String sceneInstId = data.getSceneInstId();
        if (CuccPosServiceUtils.isBatchAccept(sceneInstId)
            && KiteStringUtils.isNotEmpty(ServiceContext.getCurOfferInstId())) {
            // 批量受理转单时不单独调计价接口，设置完属性后统一计价
            // 单个修改页面需要调（根据是否有ServiceContext.curOfferInstId判断，如果不存在则认为是单个修改页面）
            return;
        }
        String custId = data.getCustId();
        String offerId = Optional.ofNullable(querySceneInstService.getMainOfferInst(data.getSceneInstId())).map(KiteOfferInst::getOfferId).orElse(null);
        List<PriceFactorDTO> priceFactors = PriceFactorsCache.get(offerId);
        // 计价因子属性值更新，或者和计价因子关联的产品属性，刷新新增资费的标准月租费
        if (KiteListUtils.isNotEmpty(priceFactors) && (priceFactors.stream().anyMatch(priceFactor -> KiteStringUtils.equals(priceFactor.getAttrCode(), attr.getFieldName())) ||
            KiteStringUtils.equals(attr.getFieldName(), "2_0000221"))) {
            // 所有的主套餐
            List<KiteOfferInst> offerInsts = Lists.newArrayList();
            offerInsts.addAll(querySceneInstService.listMainOfferInsts(sceneInstId));
            offerInsts.addAll(querySceneInstService.listPromotionOfferInsts(sceneInstId));
            for (KiteOfferInst kiteOfferInst : offerInsts) {
                if (KiteStringUtils.isEqual(kiteOfferInst.getActionType().name(), ActionType.D.name())) {
                    continue;
                }
                // 查询所有的可选包规格
                List<OfferRelInfo> offerRelInfoList = OfferCache.get(kiteOfferInst.getOfferId()).listAllOfferRels().stream().filter(offerRelInfo -> {
                    return CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType());
                }).collect(Collectors.toList());
                if (KiteListUtils.isEmpty(offerRelInfoList)) {
                    continue;
                }
                // 套餐下新增的资费
                List<KiteOfferInst> additionalOfferInsts = querySceneInstService.listAdditionalOfferInstsFromOfferInst(custId, kiteOfferInst.getOfferInstId())
                    .stream().filter(offerInst -> ActionType.A.equals(offerInst.getActionType())).collect(Collectors.toList());
                this.dealFeePrice(sceneInstId, custId, kiteOfferInst, additionalOfferInsts);
            }
        }
    }

    private void dealFeePrice(String sceneInstId, String custId, KiteOfferInst mainOfferInst, List<KiteOfferInst> additionalOfferInsts) {
        if (KiteListUtils.isEmpty(additionalOfferInsts)) {
            return;
        }
        // 获取套餐下所有资费对应的价格
        additionalOfferInsts.forEach(additionalOfferInst -> {
            Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(additionalOfferInst.getOfferId())).map(Offer::getOfferMap).orElse(null);
            String discntCode = KiteMapUtils.getString(offerMap, "discntCode");
            Map<String, Object> goodPrice = goodsPriceFactorService.getFeeProdPrice(sceneInstId, custId, mainOfferInst.getOfferId(), additionalOfferInst);
            List<Map<String, Object>> feeItemPrices = (List<Map<String, Object>>)KiteMapUtils.getObject(goodPrice, "feeItemPrice");
            if (KiteListUtils.isNotEmpty(feeItemPrices)) {
                feeItemPrices.forEach(feeItemPrice -> {
                    String price = KiteMapUtils.getString(feeItemPrice, "price");
                    String feeCode = KiteMapUtils.getString(feeItemPrice, "feeCode");
                    if (KiteStringUtils.isEqual(feeCode, discntCode)) {
                        operateSceneInstService.setAttrValue(sceneInstId, additionalOfferInst.getInstType(), additionalOfferInst.getInstId(),
                            LocalKeyConsts.STANDARD_MONTHLY_RENT, price, price);
                    }
                });
            } else {
                operateSceneInstService.setAttrValue(sceneInstId, additionalOfferInst.getInstType(), additionalOfferInst.getInstId(),
                    LocalKeyConsts.STANDARD_MONTHLY_RENT, "", "");
            }
            // 重新计算折扣率
            CalculateDiscountsUtil.calculateDiscounts(sceneInstId, custId, additionalOfferInst.getOfferInstId());
        });
    }
}
